package br.com.afi.util;

import java.util.ArrayList;
import java.util.List;

/**
 * Funções úteis para arrays.
 * 
 * @author André de Fontana Ignacio
 * @version 1.0
 * @param <T> Tipo de objeto do array
 */
public class ArraysUtil<T>
{
	/**
	 * Faz uma busca simples pelo objeto informado.<br>
	 * O método {@link Object#equals(Object)} deve ser implementado, para um melhor desempenho
	 * implemente também o método {@link Object#hashCode()}.
	 * 
	 * @param array Array onde realizada feita a busca
	 * @param t Objeto a ser encontrado
	 * @return Indice do objeto no array ou -1 se o objeto não for encontrado
	 */
	public int simpleSearch( T[] array, T t )
	{
		int index = -1;
		int i = 0;
		
		if( t != null )
		{
			for ( T o : array )
			{
				if( o.hashCode() == t.hashCode() )
				{
					if ( o.equals( t ) )
					{
						index = i;
						break;
					}
				}
				i++;
			}
		}
		return index;
	}

	/**
	 * Verifica o array contém o objeto informado.<br>
	 * O método {@link Object#equals(Object)} deve ser implementado, para um melhor desempenho
	 * implemente também o método {@link Object#hashCode()}.
	 * 
	 * @param array Array onde será realizada a busca
	 * @param t Objeto a ser encontrado
	 * @return Verdadeiro se o array possuir o objeto
	 */
	public boolean contains( T[] array, T t )
	{
		return this.simpleSearch( array, t ) != -1;
	}

	/**
	 * Obtém uma sub-lista de um array através do indice inicial (inclusive) até o indice final
	 * (exclusivo).
	 * 
	 * @param array Array
	 * @param fromIndex Indice inicial (inclusive)
	 * @param toIndex Indice final (exclusivo)
	 * @return Sub-Lista
	 */
	public List<T> subList( T[] array, int fromIndex, int toIndex )
	{
		final List<T> subList = new ArrayList<T>();
		for ( int i = fromIndex; i < toIndex; i++ )
		{
			subList.add( array[i] );
		}
		return subList;
	}

	/**
	 * Divide um array em n sublistas de acordo com o tamanho máximo informado.
	 * 
	 * @param array Array a ser dividido
	 * @param size Tamanho máximo de cada lista
	 * @return Lista de listas
	 */
	public List<List<T>> subLists( T[] array, int size )
	{
		final List<List<T>> subLists = new ArrayList<List<T>>();
		int listNumber = 0;
		int fromIndex = size * listNumber;
		int toIndex = size * ( listNumber + 1 );
		do
		{
			if ( toIndex > array.length )
			{
				toIndex = array.length;
			}
			subLists.add( this.subList( array, fromIndex, toIndex ) );
			listNumber++;

			fromIndex = ( size * listNumber ) + 1;
			toIndex = size * ( listNumber + 1 ) + 1;
		}
		while ( fromIndex < array.length );
		return subLists;
	}
}
